package com.weilan.blog.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.weilan.blog.admin.entity.SysMenu;
import com.weilan.blog.admin.mapper.SysMenuMapper;
import com.weilan.blog.admin.service.SysMenuService;
import com.weilan.blog.admin.vo.SysMenuVO;
import com.weilan.blog.base.enums.EMenuType;
import com.weilan.blog.base.enums.EStatus;
import com.weilan.blog.base.global.Constants;
import com.weilan.blog.base.serviceImpl.SuperServiceImpl;
import com.weilan.blog.common.global.MessageConf;
import com.weilan.blog.common.global.SQLConf;
import com.weilan.blog.common.global.SysConf;

import com.weilan.blog.utils.RedisUtil;
import com.weilan.blog.utils.ResultUtil;
import com.weilan.blog.utils.StringUtils;
import com.weilan.blog.utils.UpdateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

/**
 * @description:
 * @author: 孙 峰
 * @time: 2020/9/23 22:34
 */
@Service
public class SysMenuServiceImpl extends SuperServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private SysMenuService sysMenuService;

    @Override
    public Map<String, Object> getPageList(SysMenuVO categoryMenuVO) {
        Map<String, Object> resultMap = new HashMap<>();
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();

        if (StringUtils.isNotEmpty(categoryMenuVO.getKeyword()) && !StringUtils.isEmpty(categoryMenuVO.getKeyword().trim())) {
            queryWrapper.like(SQLConf.NAME, categoryMenuVO.getKeyword().trim());
        }

        if (categoryMenuVO.getMenuLevel() != 0) {
            queryWrapper.eq(SQLConf.MENU_LEVEL, categoryMenuVO.getMenuLevel());
        }
        Page<SysMenu> page = new Page<>();
        page.setCurrent(categoryMenuVO.getCurrentPage());
        page.setSize(categoryMenuVO.getPageSize());
        queryWrapper.eq(SQLConf.STATUS, EStatus.ENABLE);
        queryWrapper.orderByDesc(SQLConf.SORT);

        IPage<SysMenu> pageList = sysMenuService.page(page, queryWrapper);
        List<SysMenu> list = pageList.getRecords();

        List<String> ids = new ArrayList<>();
        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getParentUid())) {
                ids.add(item.getParentUid());
            }
        });

        if (ids.size() > 0) {
            Collection<SysMenu> parentList = sysMenuService.listByIds(ids);
            Map<String, SysMenu> map = new HashMap<>();
            parentList.forEach(item -> {
                map.put(item.getUid(), item);
            });

            list.forEach(item -> {
                if (StringUtils.isNotEmpty(item.getParentUid())) {
                    item.setParentSysMenu(map.get(item.getParentUid()));
                }
            });

            resultMap.put(SysConf.OTHER_DATA, parentList);
        }
        pageList.setRecords(list);
        resultMap.put(SysConf.DATA, pageList);
        return resultMap;
    }

    @Override
    public List<SysMenu> getAllList(String keyword) {
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.MENU_LEVEL, "1");
        if (StringUtils.isNotEmpty(keyword)) {
            queryWrapper.eq(SQLConf.UID, keyword);
        }
        queryWrapper.orderByDesc(SQLConf.SORT);
        queryWrapper.eq(SQLConf.STATUS, EStatus.ENABLE);
        queryWrapper.eq(SQLConf.MENU_TYPE, EMenuType.MENU);
        List<SysMenu> list = sysMenuService.list(queryWrapper);

        //获取所有的ID，去寻找他的子目录
        List<String> ids = new ArrayList<>();
        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getUid())) {
                ids.add(item.getUid());
            }
        });

        QueryWrapper<SysMenu> childWrapper = new QueryWrapper<>();
        childWrapper.in(SQLConf.PARENT_UID, ids);
        childWrapper.eq(SQLConf.STATUS, EStatus.ENABLE);
        Collection<SysMenu> childList = sysMenuService.list(childWrapper);


        //获取所有的二级菜单，去寻找他的子按钮
        List<String> secondMenuUids = new ArrayList<>();
        childList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getUid())) {
                secondMenuUids.add(item.getUid());
            }
        });

        QueryWrapper<SysMenu> buttonWrapper = new QueryWrapper<>();
        buttonWrapper.in(SQLConf.PARENT_UID, secondMenuUids);
        buttonWrapper.eq(SQLConf.STATUS, EStatus.ENABLE);
        Collection<SysMenu> buttonList = sysMenuService.list(buttonWrapper);

        Map<String, List<SysMenu>> map = new HashMap<>();
        buttonList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getParentUid())) {
                if (map.get(item.getParentUid()) == null) {
                    List<SysMenu> tempList = new ArrayList<>();
                    tempList.add(item);
                    map.put(item.getParentUid(), tempList);
                } else {
                    List<SysMenu> tempList = map.get(item.getParentUid());
                    tempList.add(item);
                    map.put(item.getParentUid(), tempList);
                }
            }
        });

        // 给二级菜单设置三级按钮
        childList.forEach(item -> {
            if (map.get(item.getUid()) != null) {
                List<SysMenu> tempList = map.get(item.getUid());
                Collections.sort(tempList, new Comparator<SysMenu>() {

                    /*
                     * int compare(CategoryMenu p1, CategoryMenu p2) 返回一个基本类型的整型，
                     * 返回负数表示：p1 小于p2，
                     * 返回0 表示：p1和p2相等，
                     * 返回正数表示：p1大于p2
                     */
                    @Override
                    public int compare(SysMenu o1, SysMenu o2) {

                        //按照CategoryMenu的Sort进行降序排列
                        if (o1.getSort() > o2.getSort()) {
                            return -1;
                        }
                        if (o1.getSort().equals(o2.getSort())) {
                            return 0;
                        }
                        return 1;
                    }

                });
                item.setChildSysMenu(tempList);
            }
        });


        // 给一级菜单设置二级菜单
        for (SysMenu parentItem : list) {

            List<SysMenu> tempList = new ArrayList<>();

            for (SysMenu item : childList) {

                if (item.getParentUid().equals(parentItem.getUid())) {
                    tempList.add(item);
                }
            }
            Collections.sort(tempList);
            parentItem.setChildSysMenu(tempList);
        }
        return list;
    }

    @Override
    public List<SysMenu> getButtonAllList(String keyword) {
        return null;
    }

    @Override
    public String addCategoryMenu(SysMenuVO sysMenuVO) {
        return null;
    }

    @Override
    public String editCategoryMenu(SysMenuVO sysMenuVO) {
        SysMenu sysMenu = sysMenuService.getById(sysMenuVO.getUid());
        UpdateUtil.copyNullProperties(sysMenuVO, sysMenu);
        sysMenu.updateById();
        // 修改成功后，需要删除redis中所有的admin访问路径
        // deleteAdminVisitUrl();

        return ResultUtil.result(SysConf.SUCCESS, MessageConf.DELETE_SUCCESS);
    }

    @Override
    public String deleteCategoryMenu(SysMenuVO sysMenuVO) {
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.STATUS, EStatus.ENABLE);
        queryWrapper.in(SQLConf.PARENT_UID, sysMenuVO.getUid());
        Integer menuCount = sysMenuService.count(queryWrapper);
        if (menuCount > 0) {
            return ResultUtil.result(SysConf.ERROR, MessageConf.CHILDREN_MENU_UNDER_THIS_MENU);
        }
        SysMenu sysMenu = sysMenuService.getById(sysMenuVO.getUid());
        sysMenu.setStatus(EStatus.DISABLED);
        sysMenu.setUpdateTime(LocalDateTime.now());
        sysMenu.updateById();

        return ResultUtil.result(SysConf.SUCCESS, MessageConf.DELETE_SUCCESS);
    }

    /**
     * 置顶菜单
     *
     * @param sysMenuVO
     * @return
     */
    @Override
    public String stickCategoryMenu(SysMenuVO sysMenuVO) {

        SysMenu sysMenu = sysMenuService.getById(sysMenuVO.getUid());

        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        //如果是二级菜单 或者 按钮，就在当前的兄弟中，找出最大的一个
        if (sysMenu.getMenuLevel() == Constants.NUM_TWO || sysMenu.getMenuType() == EMenuType.BUTTON) {
            queryWrapper.eq(SQLConf.PARENT_UID, sysMenu.getParentUid());
        }
        queryWrapper.eq(SQLConf.MENU_LEVEL, sysMenu.getMenuLevel());
        queryWrapper.orderByDesc(SQLConf.SORT);
        queryWrapper.last(SysConf.LIMIT_ONE);
        SysMenu maxSort = sysMenuService.getOne(queryWrapper);

        if (StringUtils.isEmpty(maxSort.getUid())) {
            return ResultUtil.result(SysConf.ERROR, MessageConf.OPERATION_FAIL);
        }
        Integer sortCount = maxSort.getSort() + 1;

        sysMenu.setSort(sortCount);
        sysMenu.setUpdateTime(LocalDateTime.now());
        sysMenu.updateById();


        return ResultUtil.result(SysConf.SUCCESS, MessageConf.OPERATION_SUCCESS);
    }
}
